popover: Listen on grab_notify from the relative-to widget
authorCarlos Garnacho <carlosg@gnome.org>
Fri, 7 Feb 2014 15:14:23 +0000 (16:14 +0100)
committerCarlos Garnacho <carlosg@gnome.org>
Fri, 7 Feb 2014 15:47:57 +0000 (16:47 +0100)
Anytime ::grab-notify comes across, the popover visibility and GTK+
grab ownership are checked, so the popover is hidden when it loses
the GTK+ by any reason.

gtk/gtkpopover.c

index ced74dc4e4a18a8cea803067fa3296007b655daa..f3505b2e1a56f44156a6aaf9cffb99f0a5ad6567 100644 (file)
@@ -84,6 +84,7 @@ struct _GtkPopoverPrivate
   guint size_allocate_id;
   guint unmap_id;
   guint scrollable_notify_id;
+  guint grab_notify_id;
   guint has_pointing_to    : 1;
   guint preferred_position : 2;
   guint final_position     : 2;
@@ -1294,6 +1295,21 @@ _gtk_popover_parent_hierarchy_changed (GtkWidget  *widget,
   g_object_unref (popover);
 }
 
+static void
+_gtk_popover_parent_grab_notify (GtkWidget  *widget,
+                                 gboolean    was_shadowed,
+                                 GtkPopover *popover)
+{
+  GtkPopoverPrivate *priv;
+
+  priv = gtk_popover_get_instance_private (popover);
+
+  if (priv->modal &&
+      gtk_widget_is_visible (GTK_WIDGET (popover)) &&
+      !gtk_widget_has_grab (GTK_WIDGET (popover)))
+    gtk_widget_hide (GTK_WIDGET (popover));
+}
+
 static void
 _gtk_popover_parent_unmap (GtkWidget *widget,
                            GtkPopover *popover)
@@ -1439,6 +1455,8 @@ gtk_popover_update_relative_to (GtkPopover *popover,
         g_signal_handler_disconnect (priv->widget, priv->size_allocate_id);
       if (g_signal_handler_is_connected (priv->widget, priv->unmap_id))
         g_signal_handler_disconnect (priv->widget, priv->unmap_id);
+      if (g_signal_handler_is_connected (priv->widget, priv->grab_notify_id))
+        g_signal_handler_disconnect (priv->widget, priv->grab_notify_id);
 
       widget_unmanage_popover (priv->widget, popover);
     }
@@ -1470,6 +1488,10 @@ gtk_popover_update_relative_to (GtkPopover *popover,
         g_signal_connect (priv->widget, "unmap",
                           G_CALLBACK (_gtk_popover_parent_unmap),
                           popover);
+      priv->grab_notify_id =
+        g_signal_connect (priv->widget, "grab-notify",
+                          G_CALLBACK (_gtk_popover_parent_grab_notify),
+                          popover);
 
       /* Give ownership of the popover to widget */
       widget_manage_popover (priv->widget, popover);